package com.hdoit.ares.logical.cust.service.impl;

import java.util.ArrayList;
import java.util.Date;

import javax.annotation.Resource;

import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.github.qcloudsms.SmsSingleSender;
import com.github.qcloudsms.SmsSingleSenderResult;
import com.hdoit.ares.logical.cust.service.ISendMsgService;
import com.tennetcn.common.aop.CommonApplicationContextUtil;
import com.tennetcn.common.dao.base.impl.SuperService;
import com.tennetcn.common.enums.pub.SmsSupplierEnum;
import com.tennetcn.common.enums.pub.YesOrNoInteger;
import com.tennetcn.common.logical.systask.dao.ISmsSendDao;
import com.tennetcn.common.logical.systask.model.SmsSend;
import com.tennetcn.common.logical.systask.model.SmsWaitSend;
import com.tennetcn.common.logical.systask.service.ISmsWaitSendService;
import com.tennetcn.common.logical.viewmodel.systask.SmsSendValidSearch;
import com.tennetcn.common.selfcommon.enums.systask.SendStatus;
import com.tennetcn.common.utils.CommonUtils;
import com.tennetcn.common.utils.DateUtils;
import com.tennetcn.common.utils.RandomUtils;
import com.tennetcn.component.sms.ISms;
import com.tennetcn.plugins.qcloud.config.QCloudConfigModel;
import com.tennetcn.plugins.qcloud.config.QCloudConfiguration;

@Component
public class SendMsgServiceImpl extends SuperService<SmsSend> implements ISendMsgService {

	@Override
	//通过模板ID，电话，IP发送消息
	public boolean sendMsgByTemplId(String phone,Integer templId,ArrayList<String> params){
		
		QCloudConfigModel qcm = QCloudConfiguration.getInstance().qcloudConfigModel;
		try {
			SmsSingleSender sender = new SmsSingleSender(qcm.getSmsAppId(), qcm.getSmsAppKey());
			SmsSingleSenderResult result = sender.sendWithParam("86", phone, templId, params, "", "", "");
			System.err.println("result+++"+result);
			return "ok".equals(result.errMsg.toLowerCase())&&result.result==0;
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return false;
	}

	private ISmsWaitSendService smsWaitSendService;
	private ISmsSendDao smsSendDao;

	public ISmsWaitSendService getSmsWaitSendService() {
		return smsWaitSendService;
	}

	@Resource
	public void setSmsWaitSendService(ISmsWaitSendService smsWaitSendService) {
		this.smsWaitSendService = smsWaitSendService;
	}

	public ISmsSendDao getSmsSendDao() {
		return smsSendDao;
	}

	@Resource
	public void setSmsSendDao(ISmsSendDao smsSendDao) {
		this.smsSendDao = smsSendDao;
	}

	// 发送短信
	public String sendMessage(SmsWaitSend smsWaitSend) {

		if (!smsWaitSendService.addModelSelective(smsWaitSend)) {
			return "短信发送失败";
		}

		ISms sms = (ISms) CommonApplicationContextUtil.getCurrentContext().getBean("smsContext");

		String resultXml = sms.sendMessage(smsWaitSend.getReceiveMobile(), smsWaitSend.getSendContent());
		if (sms.analysis(resultXml)) {
			addWaitSendToSend(smsWaitSend.getId());
		}

		return resultXml;
	}

	//
	public boolean sendMessageAnalysis(SmsWaitSend smsWaitSend) {
		String resultXml = sendMessage(smsWaitSend);

		ISms sms = (ISms) CommonApplicationContextUtil.getCurrentContext().getBean("smsContext");

		return sms.analysis(resultXml);
	}

	//无参 验证ip 和 phone
	public String sendVerifyCode(String phone, Integer templId, String ipAddress) {
		String result = validSafe(phone, ipAddress);
		if (!StringUtils.isEmpty(result)) {
			return result;
		}

		/*String code = RandomUtils.randomNumbers(6);*/
		if (sendVerifyNoCode(phone, templId, ipAddress)) {
			return "";
		}
		return "error";
	}

	// 通过电话，发送无参短信
	@Override
	public boolean sendVerifyNoCode(String phone, Integer templId, String ipAddress) {

		ISms sms = (ISms) CommonApplicationContextUtil.getCurrentContext().getBean("smsContext");

		String result = validSafe(phone, ipAddress);
		if (!StringUtils.isEmpty(result)) {
			return false;
		}

		// 总量验证
		// 每小时总量1000则发送预警短信
		if (valid1000c()) {
			if (SmsSupplierEnum.qcloud.equals(sms.getSupplier())) {
				sms.sendValidCodeByQCloud("18929359694","8888");
			} else {
				// 发一个8888的验证码给【18929359694】以示警告
				sms.sendMessage("18929359694", sms.getVerifyCode("8888"));
			}
		}
		/*// 获取验证码
		String content = sms.getVerifyCode(code);

		//
		content = sms.appendSignContent(content);*/
		String content = String.valueOf(templId);
		
		ArrayList<String> params = new ArrayList<String>();
		
		String smsId = CommonUtils.getKeyId();

		if (addToWaitSend(smsId, phone, content, ipAddress, templId)) {
			boolean sendResult = false;
			// 如果短信商为腾讯云
			if (SmsSupplierEnum.qcloud.equals(sms.getSupplier())) {
				//
				sendResult = sendMsgByTemplId(phone, templId,params);
			} else {
				// 发送其他消息
				sendResult = sms.sendMessageAnalysis(phone, content);
			}
			if (!sendResult) {
				throw new RuntimeException("短信发送失败");
			}
			return addWaitSendToSend(smsId);
		}
		return false;
	}

	//有参验证ip 和phone
	public String sendVerifyParams(String phone, Integer templId, String ipAddress,ArrayList<String> params) {
		String result = validSafe(phone, ipAddress);
		if (!StringUtils.isEmpty(result)) {
			return result;
		}

		/*String code = RandomUtils.randomNumbers(6);*/
		if (sendVerifyNoParams(phone, templId, ipAddress,params)) {
			return "";
		}
		return "error";
	}
	
	//通过电话，参数发送有参短信
	@Override
	public boolean sendVerifyNoParams(String phone, Integer templId, String ipAddress,ArrayList<String> params) {

		ISms sms = (ISms) CommonApplicationContextUtil.getCurrentContext().getBean("smsContext");

		//判断电话和IP是否在黑名单
		String result = validSafe(phone, ipAddress);
		if (!StringUtils.isEmpty(result)) {
			return false;
		}

		// 总量验证
		// 每小时总量1000则发送预警短信
		if (valid1000c()) {
			if (SmsSupplierEnum.qcloud.equals(sms.getSupplier())) {
				sms.sendValidCodeByQCloud("18929359694","8888");
			} else {
				// 发一个8888的验证码给【18929359694】以示警告
				sms.sendMessage("18929359694", sms.getVerifyCode("8888"));
			}
		}
		
		String content = String.valueOf(templId);
		
		String smsId = CommonUtils.getKeyId();

		if (addToWaitSend(smsId, phone, content, ipAddress, templId)) {
			boolean sendResult = false;
			// 如果短信商为腾讯云
			if (SmsSupplierEnum.qcloud.equals(sms.getSupplier())) {
				//
				sendResult = sendMsgByTemplId(phone, templId,params);
			} else {
				// 发送其他消息
				sendResult = sms.sendMessageAnalysis(phone, content);
			}
			if (!sendResult) {
				throw new RuntimeException("短信发送失败");
			}
			return addWaitSendToSend(smsId);
		}
		return false;
	}
	
	// 除去receiveUserId，receiveUsername参数的判断;
	private boolean addToWaitSend(String smsId, String phone, String content, String ipAddress, Integer templId) {
		return addToWaitSend(smsId, phone, content, ipAddress, templId, null, null);
	}

	// 判断 将待发送消息set进入带发送表
	private boolean addToWaitSend(String smsId, String phone, String content, String ipAddress, Integer templId, String receiveUserId, String receiveUsername) {
		System.err.println("templId"+templId);
		SmsWaitSend waitSend = new SmsWaitSend();
		waitSend.setId(smsId);
		waitSend.setReceiveMobile(phone);
		waitSend.setSendContent(String.valueOf(templId));
		waitSend.setSendDatetime(DateUtils.getCurrent());
		waitSend.setSendNow(YesOrNoInteger.yes);
		waitSend.setSendStatus(SendStatus.waitSend);

		// 判断三项属性是否为空
		if (!StringUtils.isEmpty(receiveUserId)) {
			waitSend.setReceiveUserId(receiveUserId);
		}
		if (!StringUtils.isEmpty(receiveUsername)) {
			waitSend.setReceiveUserName(receiveUsername);
		}
		if (!StringUtils.isEmpty(ipAddress)) {
			waitSend.setIpAddress(ipAddress);
		}
		return smsWaitSendService.addModelSelective(waitSend);
	}

	// 判断 添加待发送信息到发送状态
	private boolean addWaitSendToSend(String smsId) {
		// 根据主键查出待发送消息
		SmsWaitSend waitSend = smsWaitSendService.queryModel(smsId);
		// 获取需要发送对象
		SmsSend smsSend = waitSend2SmsSend(waitSend);
		// 改变发送状态
		smsSend.setSendStatus(SendStatus.send);
		// 设置发送时间
		smsSend.setSendDatetime(DateUtils.getCurrent());
		// 判断实体是否保存成功
		if (addModelSelective(smsSend)) {
			// 如果成功，则根据主键字段进行删除，方法参数必须包含完整的主键属性
			return smsWaitSendService.deleteModel(smsId);
		}
		return false;
	}

	// 将待发送信息set进入发送表//

	private SmsSend waitSend2SmsSend(SmsWaitSend waitSend) {
		SmsSend smsSend = new SmsSend();
		smsSend.setId(waitSend.getId());
		smsSend.setReceiveMobile(waitSend.getReceiveMobile());
		smsSend.setReceiveUserId(waitSend.getReceiveUserId());
		smsSend.setReceiveUserName(waitSend.getReceiveUserName());
		smsSend.setRetryCount(waitSend.getRetryCount());
		smsSend.setSendContent(waitSend.getSendContent());
		smsSend.setSendDatetime(waitSend.getSendDatetime());
		smsSend.setSendMobile(waitSend.getSendMobile());
		smsSend.setSendNow(waitSend.getSendNow());
		smsSend.setSendMobile(waitSend.getSendMobile());
		smsSend.setSendUserId(waitSend.getSendUserId());
		smsSend.setSendUserName(waitSend.getSendUserName());
		smsSend.setIpAddress(waitSend.getIpAddress());

		return smsSend;
	}

	// 判断短信状态是否改变
	public String sendVerifyCodeSafe(String phone, Integer templId, String receiveUserId, String receiveUsername) {
		// 生成随机6位随机数
		String code = RandomUtils.randomNumbers(6);

		// 判断短信状态是否改变
		if (sendVerifyCodeSafe(phone, code, templId, receiveUserId, receiveUsername)) {
			// 成功输出随机数
			return code;
		}
		// 反之输出error
		return "error";
	}

	public boolean sendVerifyCodeSafe(String phone, String code, Integer templId, String receiveUserId, String receiveUsername) {

		ISms sms = (ISms) CommonApplicationContextUtil.getCurrentContext().getBean("smsContext");

		String content = sms.getVerifyCode(code);
		content = sms.appendSignContent(content);

		String smsId = CommonUtils.getKeyId();
		
		ArrayList<String> params = new ArrayList<String>();
		
		if (addToWaitSend(smsId, phone, content, null, templId, receiveUserId, receiveUsername)) {
			boolean sendResult = false;
			if (SmsSupplierEnum.qcloud.equals(sms.getSupplier())) {
				sendResult = sendMsgByTemplId(phone, templId, params);
			} else {
				sendResult = sms.sendMessageAnalysis(phone, content);
			}
			// 发送失败抛出异常
			if (!sendResult) {
				throw new RuntimeException("短信发送失败");
			}
			// 输出 添加待发送信息到发送状态(得到true false)
			return addWaitSendToSend(smsId);
		}
		return false;
	}

	private String validSafe(String phone, String ipAddress) {
		String result = "";
		if (valid10m10cIp(ipAddress)) {
			result = "valid10m10cIp";
		} else if (valid1h30cIp(ipAddress)) {
			result = "valid1h10cIp";
		}
		// 已经有不符合规则的就直接返回
		if (!StringUtils.isEmpty(result)) {
			return result;
		}

		if (valid10m10cReceive(phone)) {
			result = "valid10m10cPhone";
		} else if (valid1h30cReceive(phone)) {
			result = "valid1h10cPhone";
		}
		if (!StringUtils.isEmpty(result)) {
			return result;
		}
		return result;
	}

	// 验证规则(非业务系统userid的情况)
	// 接收验证
	// 1小时/30条/手机号 valid1h30cR
	// 10分钟/10条/手机号 valid10m10cR
	// 发送验证
	// 1小时/30条/请求ip valid1h30cP
	// 10分钟/10条/请求ip valid10m10cP
	// 总量验证
	// 每小时总量1000则发送预警短信 valid1000c

	// 1小时/30条/手机号 valid1h30cR
	private boolean valid1h30cReceive(String phone) {
		SmsSendValidSearch search = new SmsSendValidSearch();
		search.setPhone(phone);

		Date currDate = DateUtils.getCurrent();
		search.setEndDate(currDate);
		Date oneHourAgo = DateUtils.addHour(-1, currDate);
		search.setStartDate(oneHourAgo);

		return smsSendDao.queryCount(search) >= 30;
	}

	// 10分钟/10条/手机号 valid10m10cR
	private boolean valid10m10cReceive(String phone) {
		SmsSendValidSearch search = new SmsSendValidSearch();
		search.setPhone(phone);

		Date currDate = DateUtils.getCurrent();
		search.setEndDate(currDate);
		Date tenSecondAgo = DateUtils.addSecond(-10, currDate);
		search.setStartDate(tenSecondAgo);

		return smsSendDao.queryCount(search) >= 10;
	}

	// 发送验证
	// 1小时/30条/请求ip valid1h30cP
	private boolean valid1h30cIp(String ipAddress) {
		SmsSendValidSearch search = new SmsSendValidSearch();
		search.setIpAddress(ipAddress);

		Date currDate = DateUtils.getCurrent();
		search.setEndDate(currDate);
		Date oneHourAgo = DateUtils.addHour(-1, currDate);
		search.setStartDate(oneHourAgo);

		return smsSendDao.queryCount(search) >= 30;
	}

	// 10分钟/10条/请求ip valid10m10cP
	private boolean valid10m10cIp(String ipAddress) {
		SmsSendValidSearch search = new SmsSendValidSearch();
		search.setIpAddress(ipAddress);
		;

		Date currDate = DateUtils.getCurrent();
		search.setEndDate(currDate);
		Date tenSecondAgo = DateUtils.addSecond(-10, currDate);
		search.setStartDate(tenSecondAgo);

		return smsSendDao.queryCount(search) >= 10;
	}

	// 每小时总量1000则发送预警短信 valid1000c
	private boolean valid1000c() {
		SmsSendValidSearch search = new SmsSendValidSearch();

		Date currDate = DateUtils.getCurrent();
		search.setEndDate(currDate);
		Date oneHourAgo = DateUtils.addHour(-1, currDate);
		search.setStartDate(oneHourAgo);

		return smsSendDao.queryCount(search) >= 1000;
	}
}
